package cn.git.future;

import cn.git.entity.Person;
import cn.hutool.core.collection.CollUtil;

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @description: 多任务组合处理
 * @program: bank-credit-sy
 * @author: lixuchun
 * @create: 2024-08-07
 */
public class CompletableFutureDemo12 {

    static ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5,
            50,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String[] dragRuleChainArray = {"rule1", "rule2", "异常", "rule3"};

        // 创建多个 CompletableFuture 任务
        List<CompletableFuture<Person>> futures = CollUtil.newArrayList(dragRuleChainArray).stream()
                .map(dragRuleChain -> CompletableFuture.supplyAsync(() -> {
                    try {
                        return setPerson(dragRuleChain);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }, executor).exceptionally(e -> {
                    System.out.println("执行异常：" + e.getMessage());
                    try {
                        return setPerson("报错啦，异常处理啦!");
                    } catch (InterruptedException ex) {
                        throw new RuntimeException(ex);
                    }
                }))
                .collect(Collectors.toList());

        // 创建一个 CompletableFuture，用于等待所有任务完成
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

        // 阻塞等待所有任务完成
        try {
            allFutures.join();
        } catch (CompletionException e) {
            e.printStackTrace();
        }
        // 获取所有任务的结果
        List<Person> collect = futures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());

        executor.shutdown();
    }

    public static Person setPerson(String personName) throws InterruptedException {
        if ("异常".equals(personName)) {
            Thread.sleep(5000);
            throw new RuntimeException("啦啦啦");
        }
        System.out.println("线程：" + Thread.currentThread().getName());
        Person person = new Person();
        person.setName(personName);
        return person;
    }
}
